#include "AnimationManager.h"
#include "..\Debug\DebugLog.h"
#include "..\rapidxml.hpp"
#include <fstream>

using namespace vn;

AnimationManager::AnimationManager(vn::Sprite* p_sprite) : m_currentAnimation(nullptr)
{
	m_sprite = p_sprite;
}

AnimationManager::AnimationManager(void) : m_sprite(nullptr), m_currentAnimation(nullptr){}


AnimationManager::~AnimationManager(void)
{
	if (!m_animations.empty())
	{
		for (auto it = m_animations.begin(); it != m_animations.end(); it++)
		{
			delete (*it);
			(*it) = nullptr;
		}
		m_animations.clear();
	}
}

void AnimationManager::update(const GameTime& p_gameTime)
{
	if (m_currentAnimation != nullptr)
	{
		m_currentAnimation->update(p_gameTime);
		//if (m_currentAnimation->hasFrameChanged())
		//{
			vn::IntRect rect = m_sprite->getTextureRect();
			m_sprite->setTextureRect(m_currentAnimation->currentFrame() * rect.w, m_currentAnimation->getRow() * rect.h, rect.w, rect.h);
		//}
		if (m_currentAnimation->isDone())
		{
			if (m_currentAnimation->getNextAnimation() != "")
			{
				setAnimation(m_currentAnimation->getNextAnimation());
			}
		}
	}
}

void AnimationManager::setAnimation(const std::string& p_animID)
{
	if (m_currentAnimation != nullptr)
	{
		if (m_currentAnimation->getID() == p_animID)
			return;
	}

	if (!m_animations.empty())
	{
		for (auto it = m_animations.begin(); it != m_animations.end(); it++)
		{
			if ((*it)->getID() == p_animID)
			{
				if (m_currentAnimation != nullptr)
					m_currentAnimation->reset();
				m_currentAnimation = (*it);
				break;
			}
		}
	}
}

void AnimationManager::loadAnimations(const std::string& p_filepath)
{
	std::string xmlContent;
	std::ifstream file(p_filepath);
	if (file)
	{
		std::string line;
		while (std::getline(file, line))
			xmlContent += line;
	}
	else
	{
		Debug::log("WARNING: Cannot find " + p_filepath);
	}
	std::vector<char> _xmlBuffer = std::vector<char>(xmlContent.begin(), xmlContent.end());
	_xmlBuffer.push_back('\0');
	rapidxml::xml_document<> doc;
	doc.parse<rapidxml::parse_no_data_nodes>(&_xmlBuffer[0]);
	rapidxml::xml_node<>* root = doc.first_node();
	rapidxml::xml_node<>* animation = root->first_node("animation");

	while (animation)
	{
		std::string id = animation->first_attribute("id")->value();
		int startFrame = atoi(animation->first_attribute("startframe")->value());
		int startupFrame = atoi(animation->first_attribute("startupframe")->value());
		int endframe = atoi(animation->first_attribute("endframe")->value());
		int row = atoi(animation->first_attribute("row")->value());
		int framerate = atoi(animation->first_attribute("framerate")->value());
		std::string reverseString = animation->first_attribute("reverse")->value();
		bool reverse = (reverseString == "true") ? true : false;
		std::string repeatString = animation->first_attribute("repeat")->value();
		bool repeat = (repeatString == "true") ? true : false;
		std::string rwrString = animation->first_attribute("rwr")->value();
		bool rwr = (rwrString == "true") ? true : false;
		int tr = atoi(animation->first_attribute("tr")->value());
		m_animations.push_back(new Animation(id, row, framerate, startupFrame, startFrame, endframe, tr, repeat, reverse, rwr));
		animation = animation->next_sibling();
	}
}

void AnimationManager::setNextAnimation(const std::string& p_animID, const std::string& p_nextAnimID)
{
	if (!m_animations.empty())
	{
		for (auto it = m_animations.begin(); it != m_animations.end(); it++)
		{
			if ((*it)->getID() == p_animID)
			{
				(*it)->setNextAnimation(p_nextAnimID);
			}
		}
	}
}